package com.tal.pad.eye_protection;

import android.content.Context;
import android.os.Handler;
import android.os.HandlerThread;
import android.text.TextUtils;
import android.util.Log;

import com.tal.pad.eye_protection.interfaces.NoPersonStatusCallback;
import com.tal.pad.eye_protection.interfaces.PoseDetResultImp;
import com.tal.pad.eye_protection.interfaces.ProtectEyeResultCallback;
import com.tal.pad.eye_protection.util.ModelFileUtils;

import java.io.File;
import java.util.Objects;

import kotlin.jvm.Volatile;

public class AwConDetectApi {
    private static final String TAG = "AwConDetectApi";
    private static AwConDetectApi awConDetectApi;
    @Volatile
    private boolean isHandlefinish = true;
    private Handler asyncHandler = null;
    private  HandlerThread handlerThread = new HandlerThread("ProtectEyesThread");

    private int errorCode;
    private String errorMsg;
    private String traceID;
    private int[] box;
    private int[] cls;
    private String traceID2;

    private boolean isInited=false;//是否初始化

    public static AwConDetectApi getInstance() {
        if (awConDetectApi == null) {
            awConDetectApi = new AwConDetectApi();
        }
        return awConDetectApi;
    }

    public void init(Context context, int interval) {

        handlerThread.start();
        asyncHandler = new Handler(handlerThread.getLooper());
        asyncHandler.post(() -> {
            doModelCopy(context);
            initSDK(context, interval);
        });
    }
    public void init(Context context) {
        init(context,3);
    }

    private  void doModelCopy(Context context) {
        String modelPath = ((File) Objects.requireNonNull(context.getExternalFilesDir((String) null))).getAbsolutePath();
        ModelFileUtils.copyModel(context, modelPath, "model");

    }

    public int initSDK(Context context, int interval) {
        int ret = 0;
        String modelPath = ((File) Objects.requireNonNull(context.getExternalFilesDir((String) null))).getAbsolutePath();
        String poseClsPath = modelPath + "/clf_clipped.onnx_v2.mnn";
        String poseKpPath = modelPath + "/ldmk_clipped.onnx_v2.mnn";
        long poseClsPtr = PoseDetCls.init(poseClsPath, 0);
        long poseKpPtr = PoseDetKp.init(poseKpPath, 0);
        if (poseClsPtr == 0L || poseKpPtr == 0L) {
            Log.e(TAG, "initPipeline  error: pose init failed");
            ret = -1;
        } else {
            ret = PoseDetPipeline.init(poseKpPtr, poseClsPtr, interval);
        }
        if (ret==10000000){
            isInited=true;
        }else {
            isInited=false;
            Log.e(TAG, "initPipeline  error: pipline init failed");
        }
        return ret;
    }


    public void releaseSDK() {
        asyncHandler.post(() -> {
            PoseDetPipeline.release();
            this.isInited=false;
        });
    }
    public  boolean isInited() {
        return isInited;
    }
    /**
     * process
     *
     * @param data    图片数据
     * @param w       宽
     * @param h       高
     * @param degree  旋转角度
     * @param flip    翻转
     * @param mode    数据格式 NV21/YUV420  0:YUV420 1:NV21
     * @param traceID 跟踪id
     */
    public void detectFrame(byte[] data, int w, int h, int degree, int flip, int mode, String traceID) {
        if (!isInited){
            Log.e(TAG, "detectFrame: 初始化失败不进行其他操作");
            return;
        }
        if (!isHandlefinish) {
            Log.e(TAG, "detectFrame: 尚未处理完成，不给算法数据");
            return;
        }
        asyncHandler.post(() -> {
            isHandlefinish = false;
            PoseDetPipeline.process(data, w, h, degree, flip, mode, traceID);
            isHandlefinish = true;
        });
    }
    public void detectFrameTest(String path, String traceID){
        if (!isInited){
            Log.e(TAG, "detectFrame: 初始化失败不进行其他操作");
            return;
        }
        if (!isHandlefinish) {
            Log.e(TAG, "detectFrame: 尚未处理完成，不给算法数据");
            return;
        }
        asyncHandler.post(() -> {
            isHandlefinish = false;
            PoseDetPipeline.processTest(path, traceID);
            isHandlefinish = true;
        });
    }
    public void resetResult() {
        asyncHandler.post(() -> {
            PoseDetPipeline.resetResult();
        });
    }

    public void getResult(final ProtectEyeResultCallback callback) {
        if (!isInited){
            Log.e(TAG, "detectFrame: 初始化失败不进行其他操作");
            return;
        }
        asyncHandler.post(() -> {
            ResultInfo resultInfo = PoseDetPipeline.getResult();
            if (resultInfo == null) {
                Log.e(TAG, "getResult returned null ResultInfo");
                return; // 或者做其他错误处理
            }
            Log.e(TAG, "getResult: " + resultInfo.yawn_count + " " + resultInfo.sleep_time + " " + resultInfo.prostrate_time + " " + resultInfo.headdown_time + " " + resultInfo.lookdown_time + " " + resultInfo.headup_time + " " + resultInfo.lookup_time + " " + resultInfo.headtilt + " " + resultInfo.faceprofile + " " + resultInfo.lookaround + " " + resultInfo.shouldertilt + " " + resultInfo.liedown);
            if (callback != null) {
                callback.onResult(resultInfo);
            }

        });
    }

    public void setErrorInfo(int errorCode, String errorMsg, String traceID) {
        this.errorCode = errorCode;
        this.errorMsg = errorMsg;
        this.traceID = traceID;
    }

    public void setPoseDetResult(int[] box, int[] cls, String traceID) {
        this.box = box;
        this.cls = cls;
        this.traceID2 = traceID;
    }

    public void getPoseDetBridgeInfo(PoseDetResultImp poseDetResultImp) {
        asyncHandler.post(() -> {
            if (poseDetResultImp != null) {
                if (!TextUtils.isEmpty(traceID)){
                    poseDetResultImp.onError(errorCode, errorMsg, traceID);

                }
                if (!TextUtils.isEmpty(traceID2)){
                    poseDetResultImp.onResult(box, cls, traceID2);

                }
            }
        });

    }
    public void getNoPersonStatus(NoPersonStatusCallback callback){
        if (!isInited){
            Log.e(TAG, "detectFrame: 初始化失败不进行其他操作");
            return ;
        }
        asyncHandler.post(() -> {
            int noPersonStatus = PoseDetPipeline.getNoPersonStatus();
            if (callback != null) {
                callback.onNoPersonStatus(noPersonStatus);
            }
        });
    }
}
